package org.xlp.base.application.context;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xlp.assertion.AssertUtils;
import org.xlp.mvc.context.ApplicationContext;
import org.xlp.mvc.context.ApplicationContextException;
import org.xlp.mvc.context.ApplicationContextUtils;
import org.xlp.scanner.pkg.ScannerAnnotationParser;
import org.xlp.scanner.pkg.ScannerPkg;

/**
 * Description: 应用上下文
 * <br/>date: 2023/12/28 16:35
 *
 * @version 1.0
 * @author: xlp
 */
public class AppApplicationContext extends ApplicationContext {
    private final static Logger LOGGER = LoggerFactory.getLogger(AppApplicationContext.class);

    /**
     * 构造函数
     */
    public AppApplicationContext() {
        super();
        setBeansContainer(new ApplicationBeansContainer());
    }

    /**
     * 构造函数
     *
     * @param classLoader
     * @param packages    要扫描的包路径
     */
    public AppApplicationContext(ClassLoader classLoader, String[] packages) {
        super(classLoader, packages);
        setBeansContainer(new ApplicationBeansContainer());
    }

    /**
     * 构造函数
     *
     * @param classLoader
     * @param scannerPkg  包扫描器
     */
    public AppApplicationContext(ClassLoader classLoader, ScannerPkg scannerPkg) {
        super(classLoader, scannerPkg);
        setBeansContainer(new ApplicationBeansContainer());
    }

    /**
     * 构造函数
     *
     * @param classLoader
     * @param packages    要扫描的包路径
     * @param scannerPkg  包扫描器
     */
    public AppApplicationContext(ClassLoader classLoader, String[] packages, ScannerPkg scannerPkg) {
        super(classLoader, packages, scannerPkg);
        setBeansContainer(new ApplicationBeansContainer());
    }

    /**
     * 创建上下文
     * @param parseClass 要解析的配置类，通过该配置了加载到哪些包需要扫描
     * @return 上下文
     * @throws NullPointerException 假如参数为null，则抛出该异常
     */
    public static ApplicationContext create(Class<?> parseClass) throws ApplicationContextException {
        return create(parseClass, AppApplicationContext.class.getClassLoader());
    }

    /**
     * 创建上下文
     * @param parseClass 要解析的配置类，通过该配置了加载到哪些包需要扫描
     * @return 上下文
     * @throws NullPointerException 假如第一个参数为null，则抛出该异常
     */
    public static ApplicationContext create(Class<?> parseClass, ClassLoader classLoader)
            throws ApplicationContextException {
        AssertUtils.isNotNull(parseClass, "parseClass parameter must not be null!");
        ApplicationContext context = new AppApplicationContext(classLoader, new ScannerAnnotationParser(classLoader, parseClass))
                .complete();
        //把创建好的上下文放入缓存中
        ApplicationContextUtils.pushContext(context);
        return context;
    }
}
